﻿using SqlSugar;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Zocono.Infrastructure.Common;
using Zocono.WCS.Domain.DomainRepository;
using Zocono.WCS.Domain.EntityInfo;
using Zocono.WCS.Infrastructure.ApllicationDto.WCSTaskDto;
using Zocono.WCS.Infrastructure.ApllicationDto;
using Zocono.WCS.Infrastructure.ApllicationDto.DtoWcsManage;
using AutoMapper;

namespace Zocono.WCS.Domain.ProgrameDomain
{
    public class ProgrameService : IProgrameService
    {
        private readonly ILogUtil _LogUtil;
        private readonly ISnowflake _Snowflake;
        private readonly IProgrameInfoRepository _ProgrameInfoRepository;

        public ProgrameService(IProgrameInfoRepository programeInfoRepository
            , ILogUtil logUtil
            , ISnowflake snowflake)
        {
            _ProgrameInfoRepository = programeInfoRepository;
            _LogUtil = logUtil;
            _Snowflake = snowflake;
        }
        public async Task<List<ProgrameInfo>> GetAllProgrameInfo()
        {
            var programeInfos = await _ProgrameInfoRepository.GetListAsync();
            return programeInfos;
        }

        public async Task<ProgrameInfo> GetProgrameInfo(string programeCode)
        {
            var exp = Expressionable.Create<ProgrameInfo>().And(p => p.ProgrameCode == programeCode).ToExpression();
            var programeInfo = await _ProgrameInfoRepository.GetFirstAsync(exp);
            return programeInfo;
        }

        public async Task<bool> ProgrameStart(string programeCode)
        {
            bool isOk = await _ProgrameInfoRepository.UpdateAsync(
                p => new ProgrameInfo { IsStart = true, StartTime = DateTime.Now, TickTime = DateTime.Now },
                p => p.ProgrameCode == programeCode);

            return isOk;
        }

        public async Task<bool> PromgrameTick(string programeCode)
        {
            try
            {
                bool isOk = await _ProgrameInfoRepository.UpdateAsync(
                    p => new ProgrameInfo { IsStart = true, TickTime = DateTime.Now },
                    p => p.ProgrameCode == programeCode);

                return isOk;
            }
            catch (Exception ex)
            {
                _LogUtil.Error(ex.ToString());
            }
            return false;
        }

        public async Task<bool> ProgrameStop(string programeCode)
        {
            bool isOk = await _ProgrameInfoRepository.UpdateAsync(
                p => new ProgrameInfo { IsStart = false, TickTime = DateTime.Now },
                p => p.ProgrameCode == programeCode);

            return isOk;
        }


        public async Task<PageDto<ProgrameInfo>> GetPagedProgrameInfoAsync(QueryProgrameInfoDto queryProgrameInfo)
        {
            var exp = Expressionable.Create<ProgrameInfo>();
            exp.AndIF(!string.IsNullOrEmpty(queryProgrameInfo.ProgrameCode), it => it.ProgrameCode.Contains(queryProgrameInfo.ProgrameCode));
            exp.AndIF(!string.IsNullOrEmpty(queryProgrameInfo.ProgrameName), it => it.ProgrameName.Contains(queryProgrameInfo.ProgrameName));

            PageDto<ProgrameInfo> pagedData = new PageDto<ProgrameInfo>();
            RefAsync<int> totalCount = 0;

            var result = await _ProgrameInfoRepository.AsSugarClient().Queryable<ProgrameInfo>()
                .Where(exp.ToExpression())
                .ToPageListAsync(queryProgrameInfo.PageIndex, queryProgrameInfo.PageSize, totalCount);

            pagedData.Result = result;
            pagedData.Total = totalCount;

            return pagedData;
        }

        public async Task<bool> CreateProgrameInfoAsync(ProgrameInfo programeInfo)
        {
            programeInfo.ID = _Snowflake.GetId();
            programeInfo.IsStart = false;
            programeInfo.StartTime = new DateTime(1900, 1, 1);
            programeInfo.TickTime = new DateTime(1900, 1, 1);

            bool isOk = await _ProgrameInfoRepository.InsertAsync(programeInfo);

            return isOk;
        }

        public async Task<bool> ModifyProgrameInfoAsync(ProgrameInfo programeInfo)
        {
            bool isOk = await _ProgrameInfoRepository.UpdateAsync(
                p => new ProgrameInfo
                {
                    ProgrameCode = programeInfo.ProgrameCode,
                    ProgrameName = programeInfo.ProgrameName
                },
                p => p.ID == programeInfo.ID);

            return isOk;
        }

        public async Task<bool> DeleteProgrameInfoAsync(List<ProgrameInfo> programeInfoList)
        {
            try
            {
                _ProgrameInfoRepository.AsTenant().BeginTran();

                foreach (var item in programeInfoList)
                {
                    await _ProgrameInfoRepository.DeleteByIdAsync(item.ID);
                }

                _ProgrameInfoRepository.AsTenant().CommitTran();

                return true;
            }
            catch (Exception ex)
            {
                _ProgrameInfoRepository.AsTenant().RollbackTran();

                throw new Exception(ex.Message);
            }
        }

        public async Task<ProgrameInfo> GetProgrameInfoByIdAsync(long id)
        {
            var result = await _ProgrameInfoRepository.GetByIdAsync(id);
            return result;
        }

        public async Task<bool> DelectProgrameByIdAsync(long id)
        {
            var result = await _ProgrameInfoRepository.DeleteByIdAsync(id);
            return result;
        }
    }
}
